package main

import (
	"time"
	"global/libs/ws"
	"github.com/ngaut/log"
	"global/constants"
	"encoding/json"
	"global/core"
	"strings"
	"global/util"
)

type CoinRequest struct {
	req 				*ws.CoinListRequest
	handler 			*Handler
	ticker 				*time.Ticker

	exit 				chan interface{}
}

func (h *CoinRequest) Init() {
	h.req = nil
	h.exit  = make(chan interface{})
	h.ticker = time.NewTicker(2 * time.Second)
	h.timeTicker()
}

func (h *CoinRequest) Clear()  {
	h.exit <- true
}

func (h *CoinRequest) ReadWriteMessage(handler *Handler, message ws.RequestMessage) error {
	h.handler = handler

	var r ws.CoinListRequest
	msg := []byte(message.Message)
	err := json.Unmarshal(msg, &r)
	if err != nil {
		return err
	}

	if (r.Sort != "mv" && r.Sort != "price" && r.Sort != "percent") ||
		(r.Direction != "desc" && r.Direction != "asc") {
		h.handler.response <- ws.ErrorMsg(ws.ErrParameter, constants.RequestCoin)
		return nil
	}

	h.req = &r

	return h.list()
}

func (h *CoinRequest) timeTicker() {
	go func() {
		for {
			select {
			case <-h.exit:
				h.ticker.Stop()
				return
			case <-h.ticker.C:
				if err := h.list(); err != nil {
					log.Errorf("Error: catch error and return %s", err)
					h.handler.broke <- err
					return
				}
			}
		}
	}()
}

func (h *CoinRequest) list() error {

	if h.req == nil {
		return nil
	}

	start := time.Now()
	conn := h.handler.ctx.GetBaseRedis().Get()
	defer conn.Close()

	total, strs, err := core.GetCoinList(conn, *h.req, constants.SortTypeDesc)
	if err != nil {
		return err
	}

	rate, err := core.GetCnyRateByCoin(conn, "usd")
	if err != nil {
		return err
	}

	// 倒序
	coins := make([]string, 0)
	if h.req.Direction == "desc" {
		for i := len(strs) - 1; i >= 0; i-- {
			coins = append(coins, strs[i])
		}
	} else {
		coins = strs
	}

	datas := make([]ws.CoinItem, 0)
	for _, coin := range coins {
		ticker, meta, err := core.GetCoinMetaAndTicker(conn, coin)
		if err != nil {
			return err
		}

		data := ws.CoinItem{
			Mid: 			meta.Mid,
			Symbol: 		strings.ToUpper(meta.Symbol),
			Logo: 			util.ImageUrl(h.handler.ctx.GetImgUrl(), meta.Logo),
			NameEn: 		meta.NameEn,
			NameCn: 		meta.NameCn,
			MarketValueUSD:	ticker.MarketValue,
			MarketValueCNY: util.GetUsdToCny(ticker.MarketValue, rate),
			Percent: 		ticker.Percent,
			PriceUSD: 		ticker.Close,
			PriceCNY: 		util.GetUsdToCny(ticker.Close, rate),
			UsdCny: 		rate,
		}

		datas = append(datas, data)
	}

	var response ws.CoinListResponse
	response.Data = datas
	response.Total = total
	response.Page = h.req.Page
	response.PageSize = constants.PageSize

	h.handler.response <- ws.WsResponse(response, constants.RequestCoin)

	log.Infof("get response data success: count: %d, take time: %s", len(datas), time.Since(start))
	return nil
}

